/**
 *
 */
package org.whuims.pois.dao;

import org.apache.logging.log4j.core.helpers.Strings;
import org.whuims.pois.action.result.DataVo;
import org.whuims.pois.action.result.SiteCountVo;
import org.whuims.pois.action.result.WeixinBlogVo;
import org.whuims.pois.common.TimeUtils;
import org.whuims.pois.hibernate.BaseDao;
import org.whuims.pois.model.Cluster;
import org.whuims.pois.model.DataC;
import org.whuims.pois.model.Stare;

import java.sql.Timestamp;
import java.util.*;

/**
 * @author herochen
 * @date 2010-4-19 @time 下午01:25:39
 */
public class NewsDao {

    BaseDao baseDao = new BaseDao();

    /**
     * 构造查询最新指定类型数据的sql语句
     */
    public List<DataVo> getNewest(String type, long topicid, String userName) {
        List<org.whuims.pois.action.result.DataVo> list = baseDao.queryByParamArr(1, 50, "select new org.whuims.pois.action.result.DataVo(id,titlecontent,titlelink,abstext,sitename,newstime,crawltime) from DataC where topicid=? and type= ? and status=0 order by newstime desc", topicid, type);
        checkStarStatus(userName, list);
        return list;
    }

    public List<DataVo> getNewestWithLanguage(String type, long topicid, String userName, String language) {
        List<org.whuims.pois.action.result.DataVo> list = null;
        if (language.equals("all")) {
            list = baseDao.queryByParamArr(1, 50, "select new org.whuims.pois.action.result.DataVo(id,titlecontent,titlelink,abstext,sitename,newstime,crawltime) from DataC where topicid=? and type=? and status=0 order by newstime desc", topicid, type);
        } else
            list = baseDao.queryByParamArr(1, 50, "select new org.whuims.pois.action.result.DataVo(id,titlecontent,titlelink,abstext,sitename,newstime,crawltime) from DataC where topicid=? and type=? and planguage=? and status=0 order by newstime desc", topicid, type, language);
        checkStarStatus(userName, list);
        return list;
    }

    /**
     * 统计
     *
     * @return
     */
    public int[] statistic(long topicId, String start, String end) {
        int[] r = new int[6];
        int news = getNewsCount("news", topicId, null, start, end);
        int bbs = getNewsCount("bbs", topicId, null, start, end);
        int weibo = getNewsCount("weibo", topicId, null, start, end);
        int weixin = getNewsCount("weixin", topicId, null, start, end);
        int blog = getNewsCount("blog", topicId, null, start, end);
        r[0] = news + bbs + weibo + weixin + blog;
        r[1] = news;
        r[2] = bbs;
        r[3] = weibo;
        r[4] = weixin;
        r[5] = blog;
        return r;
    }

    public List<DataVo> getWeixinBlogs(long topicId, long crawlId, String userName) {
        int n = this.baseDao.getTotalCount("from DataC where topicid=\'" + topicId + "\'and crawlerid=\'" + crawlId + "\'");
        List<DataVo> result = this.baseDao.queryLast(n - 50, n, "select new org.whuims.pois.action.result.DataVo(id,titlecontent,titlelink,abstext,sitename,newstime,topicid,crawltime) from DataC where topicid=\'" + topicId + "\'and crawlerid=\'" + crawlId + "\'");
        checkStarStatus(userName, result);
        return result;
    }

    private void checkStarStatus(String userName, List<DataVo> list) {
        List<Long> starList = baseDao.findByParamsArr("select dataid from Stare where user=?", userName);
        for (int i = 0; i < list.size(); i++) {
            DataVo dataVo = list.get(i);
            if (starList.contains(dataVo.getId())) {
                dataVo.setStar(true);
            }
        }
    }

    /**
     * 获取对应语种的新闻的条数
     *
     * @return
     */
    public int getNewsCount(String type, Long topicId, String language, String startDate,
                            String endDate) {
        List list = new ArrayList();
        //得到hql，并填充参数列表
        String prefix = ""; //count的prefix为""
        String hql = getQuery(prefix, type, topicId, language, startDate, endDate, list);

        int count = baseDao.getTotalCountByListParams(hql, list);
        return count;
    }

    /**
     * 得到一个查询
     *
     * @param prefix    select前缀
     * @param type      数据类型：bbs，news等
     * @param topicId   主题ID，不能为空
     * @param language  语种，可以为空
     * @param startDate 可以为空
     * @param endDate   可以为空
     * @param list      填充的参数列表
     * @return
     */
    private String getQuery(String prefix, String type, Long topicId, String language, String startDate, String endDate, List list) {

        if (Strings.isEmpty(startDate) || !startDate.matches("\\d\\d\\d\\d-\\d\\d-\\d\\d")) {
            startDate = null;
        }
        if (Strings.isEmpty(endDate) || !endDate.matches("\\d\\d\\d\\d-\\d\\d-\\d\\d")) {
            endDate = null;
        }
        if (Strings.isEmpty(language) || language.trim().equals("all")) {
            language = null;
        }
        //topicId
        //type
        //language
        Timestamp startTime = TimeUtils.getTimestamp(startDate, true);
        Timestamp endTime = TimeUtils.getTimestamp(endDate, false);
        String hql = prefix + "from DataC where topicId = ? and type=? ";
        list.add(topicId);
        list.add(type);
        if (language != null) {
            hql += " and planguage = ?";
            list.add(language);
        }
        if (startTime != null) {
            hql += " and newstime >=?";
            list.add(startTime);
        }
        if (endTime != null) {
            hql += " and newstime <=?";
            list.add(endTime);
        }
        return hql;
    }

    /**
     * 查看负面新闻
     */
    public List<DataVo> getNegative(String userName, String type, Long topicId) {
        String sql = "select new org.whuims.pois.action.result.DataVo(id,titlecontent,titlelink,abstext,sitename,newstime,topicid,crawltime,negativeindex) from DataC where topicid=? and type= ? and negativeindex >= 10  and status=0 order by newstime desc";
        List<DataVo> list = baseDao.queryByParamArr(0, 100, sql, topicId, type);
        checkStarStatus(userName, list);
        return list;
    }

    /**
     * 查看被关注的新闻
     */
    public List<org.whuims.pois.action.result.DataVo> starNews(String userName, Long topicId, String type) {

        //user topicid dataid
        //取得当前用户关注新闻的id数组
        List<Stare> stareList = baseDao.find("from Stare where user='" + userName + "'");
        int length = stareList.size();
        Long[] dataId = new Long[length];
        for (int i = 0; i < length; i++) {
            dataId[i] = stareList.get(i).getDataid();
        }
        String temp = "";
        for (int i = 0; i < dataId.length; i++) {
            temp = temp + dataId[i] + ",";
        }
        temp = temp.substring(0, temp.length() - 1);
        String sql = "select id,titlecontent,titlelink,abstext,newstime,sitename,importance, negativeindex, topicid, type from data_c where type='" + type + "' and topicid='" + topicId + "' and id in (" + temp + ")";
        List list = baseDao.findBySql(sql);
        List<org.whuims.pois.action.result.DataVo> newslist = new ArrayList<org.whuims.pois.action.result.DataVo>();
        for (int i = 0; i < list.size(); i++) {
            newslist.get(i).setId((Long) list.get(i));
            newslist.get(i).setTitle((String) list.get(i));
            newslist.get(i).setLink((String) list.get(i));
            newslist.get(i).setAbstext((String) list.get(i));

            newslist.get(i).setSite((String) list.get(i));

//            newslist.get(i).setTopic(topicId);

        }
        for (org.whuims.pois.action.result.DataVo bean : newslist) {
            String titleContent = bean.getTitle();
            if (titleContent.length() > 13) {
                titleContent = titleContent.substring(0, 13).concat("..");
                bean.setTitle(titleContent);
            }
        }
        return newslist;
    }

    public List<List<Calendar>> timeserial(String type, Long topicId, String language, String startDate,
                                           String endDate) {
        List<List<Calendar>> list = new ArrayList<List<Calendar>>();
        String[] hql = new String[5];
        List<List> paramsList = new ArrayList<List>();
        if (Strings.isEmpty(type)) {    //四个系列
            List params1 = new ArrayList();
            hql[0] = getQuery("SELECT newstime ", "news", topicId, language, startDate, endDate, params1) + " ORDER BY newstime desc";
            List params2 = new ArrayList();
            hql[1] = getQuery("SELECT newstime ", "bbs", topicId, language, startDate, endDate, params2) + " ORDER BY newstime desc";
            List params3 = new ArrayList();
            hql[2] = getQuery("SELECT newstime ", "weibo", topicId, language, startDate, endDate, params3) + " ORDER BY newstime desc";
            List params4 = new ArrayList();
            hql[3] = getQuery("SELECT newstime ", "blog", topicId, language, startDate, endDate, params4) + " ORDER BY newstime desc";
            List params5 = new ArrayList();
            hql[4] = getQuery("SELECT newstime ", "weixin", topicId, language, startDate, endDate, params5) + " ORDER BY newstime desc";
            paramsList.add(params1);
            paramsList.add(params2);
            paramsList.add(params3);
            paramsList.add(params4);
            paramsList.add(params5);
        } else {
            List params1 = new ArrayList();
            hql[0] = getQuery("SELECT newstime ", type, topicId, language, startDate, endDate, params1) + " ORDER BY newstime desc";
            paramsList.add(params1);
        }
        dataTimeSerial(list, hql, paramsList);

        return list;
    }

    /**
     * 某种type的所有时间
     *
     * @param list
     * @param hql
     */
    private void dataTimeSerial(List<List<Calendar>> list, String[] hql, List<List> params) {
        for (int j = 0; j < hql.length; j++) {
            if (hql[j] == null) {
                break;
            }
            List<Timestamp> result = baseDao.findByParamsList(hql[j], params.get(j));
            List<Calendar> calendarList = new ArrayList<Calendar>();
            for (int i = 0; i < result.size(); i++) {
                if (result.get(i) == null) {
                    continue;
                }
                calendarList.add(TimeUtils.date2Calendar(new Date(result.get(i).getTime())));
            }
            list.add(calendarList);
        }
    }


    /**
     * 得到排名前20的站点分布
     *
     * @param topicId
     * @param language
     * @param startDate
     * @param endDate
     * @return
     */
    public List<Map<String, Long>> sitedist(String type, Long topicId, String language, String startDate,
                                            String endDate) {

        List<Map<String, Long>> list = new ArrayList<Map<String, Long>>();  //list的每项是一个序列，map的每项是一个数据
        List params = new ArrayList();
        String hql[] = new String[5];
        final String prefix = "SELECT new org.whuims.pois.action.result.SiteCountVo(sitename, COUNT(*)) ";
        final String surfix = " GROUP BY sitename ORDER BY count(*) desc";
        List<List> paramsList = new ArrayList<List>();
        if (Strings.isEmpty(type)) {
            List params1 = new ArrayList();
            hql[0] = getQuery(prefix, "news", topicId, language, startDate,
                    endDate, params1) + surfix;
            List params2 = new ArrayList();
            hql[1] = getQuery(prefix, "bbs", topicId, language, startDate,
                    endDate, params2) + surfix;
            List params3 = new ArrayList();
            hql[2] = getQuery(prefix, "weibo", topicId, language, startDate,
                    endDate, params3) + surfix;
            List params4 = new ArrayList();
            hql[3] = getQuery(prefix, "blog", topicId, language, startDate,
                    endDate, params4) + surfix;
            List params5 = new ArrayList();
            hql[4] = getQuery(prefix, "weixin", topicId, language, startDate,
                    endDate, params5) + surfix;
            paramsList.add(params1);
            paramsList.add(params2);
            paramsList.add(params3);
            paramsList.add(params4);
            paramsList.add(params5);
        } else {
            List params1 = new ArrayList();
            hql[0] = getQuery(prefix, type, topicId, language, startDate,
                    endDate, params1) + surfix;
            paramsList.add(params1);
        }
        dataSiteDist(list, hql, paramsList);
        return list;
    }

    /**
     * 某种type的站点分布数据
     *
     * @param list
     * @param hql
     */
    private void dataSiteDist(List<Map<String, Long>> list, String[] hql, List<List> params) {
        String[] otherName = new String[]{"其他新闻", "其他论坛", "其他微博", "其他博客", "未知"};
        for (int j = 0; j < hql.length; j++) {
            if (hql[j] == null) {
                break;
            }
            List<SiteCountVo> result = baseDao.findByParamsList(hql[j], params.get(j));
            int count = 0;
            Map<String, Long> map = new HashMap<String, Long>();
            for (int i = 0; i < result.size(); i++) {
                count++;
                if (count <= 20) {
                    map.put(result.get(i).getSiteName(), result.get(i).getCount());
                } else {
                    if (map.containsKey(otherName[j])) {
                        map.put(otherName[j], map.get(otherName[j]) + result.get(i).getCount());
                    } else {
                        map.put(otherName[j], result.get(i).getCount());
                    }
                }
            }
            //TODO 多系列
            list.add(map);
        }

    }


    /**
     * 得到一个新闻列表
     *
     * @param type
     * @param topicId
     * @param language
     * @param startDate
     * @param endDate
     * @param start
     * @param pageSize
     * @return
     */
    public List<DataVo> getNews(String type, Long topicId, String language, String startDate, String endDate, int start, int pageSize) {
        String prefix = "select new org.whuims.pois.action.result.DataVo(id,titlecontent,titlelink,abstext,sitename,newstime,crawltime) ";
        List list = new ArrayList();
        if (Strings.isEmpty(type)) {
            type = "news";
        }
        String query = getQuery(prefix, type, topicId, language, startDate, endDate, list) + " order by newstime desc";
        ;
        List<DataVo> result = baseDao.queryByParamList(start, pageSize, query, list);
        return result;
    }

    public List<DataVo> getSimilar(long topicId, long id) {
        Cluster cluster = getCluster(id);
        String similarIds = cluster.getSimilarid();
        if (Strings.isEmpty(similarIds)) {
            return new ArrayList<DataVo>();
        }
        String hql = "select new org.whuims.pois.action.result.DataVo(id,titlecontent,titlelink,abstext,sitename,newstime,crawltime) " +
                "from DataC where id in(" + similarIds + ")";
        return baseDao.find(hql);
    }

    public Cluster getCluster(long id) {
        Cluster c = (Cluster) baseDao.getByPk(Cluster.class, id);
        DataC dataC = (DataC) baseDao.getByPk(DataC.class, c.getRecordid());
        c.setName(dataC.getTitlecontent());
        return c;
    }
}
